<?php
/**
 * User: YL
 * Date: 2019/08/22
 */

namespace restful\utils\log;

use restful\traits\InstanceTrait;
use restful\utils\Env;
use think\Container;

class FileHandler
{
    use InstanceTrait;

    /**
     * @var string
     */
    protected $path = 'runtime/logs/';

    /**
     * @var string
     */
    protected $maxSize = '2m';

    /**
     * @var int
     */
    protected $maxFiles = '30';

    /**
     * @var string
     */
    protected $savePath;

    private function __construct()
    {
        $this->init();
    }

    /**
     * 初始化操作
     */
    protected function init()
    {
        $log = Env::get('log');

        $this->path = $log['path'] ?? $this->path;
        $this->maxSize = $log['max_size'] ?? $this->maxSize;
        $this->maxFiles = $log['max_files'] ?? $this->maxFiles;

        $basePath = Container::getInstance()->get('app')->getRootPath();
        $this->savePath = $basePath . $this->path;

        $this->checkDir();
        $this->checkMaxFiles();
    }

    /**
     * 是否调试模式
     * @return mixed
     */
    public function isDebug()
    {
        return Env::get('log.debug', false);
    }

    /**
     * 写入文件
     * @param string $name
     * @param string $msg
     * @return bool
     */
    public function write(string $name, string $msg)
    {
        $name = $this->buildName($name);
        $msg = $this->buildMsg($msg);

        $this->checkMaxSize($name);

        return !! file_put_contents($name, $msg, FILE_APPEND);
    }

    /**
     * 生成路径
     * @param string $name
     * @return string
     */
    protected function buildName(string $name)
    {
        return sprintf(
            '%s%s.%s.log',
            $this->savePath,
            date('Y-m-d'),
            $name
        );
    }

    /**
     * 生成消息
     * @param string $msg
     * @return string
     */
    protected function buildMsg(string $msg)
    {
        return sprintf(
            '[%s]%s%s%s',
            date('Y-m-d H:i:s'),
            PHP_EOL,
            $msg,
            PHP_EOL
        );
    }

    /**
     * 检测路径
     */
    protected function checkDir()
    {
        if (! is_dir($this->savePath)) {
            mkdir($this->savePath, 0755, true);
        }
    }

    /**
     * 检测最大文件数量
     */
    protected function checkMaxFiles()
    {
        if ($this->maxFiles) {
            $files = glob($this->savePath . '*.log');
            if (count($files) > $this->maxFiles) {
                unlink($files[0]);
            }
        }
    }

    /**
     * 检测最大文件占用量
     * @param string $name
     */
    protected function checkMaxSize(string $name)
    {
        $fileSize = FileSize::get($this->maxSize);
        if (is_file($name) && floor($fileSize) <= filesize($name)) {
            rename($name, dirname($name) . DIRECTORY_SEPARATOR . time() . '-' . basename($name));
        }
    }
}